#pragma once

// 智能指针
template <class T>
class SharedPtr
{
public:
    SharedPtr(T* ptr)
        : _pCnt(new int(1)),
        _ptr(ptr)
    {}

    SharedPtr(const SharedPtr<T>& s) // 拷贝构造
    :_ptr(s._ptr),
    _pCnt(s._pCnt)
    {
        ++(*_pCnt);
    }

    SharedPtr<T>& operator=(const SharedPtr<T>& s)
    {
        if(this != &s)
        {
            // 先处理自己
            Release();
            // 拷贝
            _ptr = s._ptr;
            _pCnt = s._pCnt;
            ++(*_pCnt);
        }
        return *this;
    }

    virtual ~SharedPtr()
    {
        Release(); // _cnt为1时释放空间
    }

public:
    T* Get()
    {
        return _ptr;
    }

    T* operator->()
    {
        return _ptr;
    }

    T& operator*()
    {
        return *_ptr;
    }

    int Count()
    {
        return *_pCnt;
    }

private:
    void Release()
    {
        if(*_pCnt == 1)
        {
            delete _pCnt;
            delete _ptr;
            _ptr = nullptr;
        }
        else
        {
            --(*_pCnt);
        }
    }

private:
    int *_pCnt; // 引用计数
    T* _ptr; // 原始指针
};